from openphantasy.utils import json_response
from openphantasy.server.models import Country, Team, League
from django.http import HttpResponse
###############################################################################
# Service Base class
###############################################################################
class ServiceBase(object):
    def __init__(self, request):
        self._r = request
        self._operationType = self.r('_operationType')
        self._old = self.r('_oldValues')
        self._data = {}
        
    def r(self, key):
        """Retrieve from request.REQUEST
        """
        return self._r.REQUEST.get(key)
    
    def d(self, key):
        """Retrieve from self._data
        """
        return self._data[key]
    
    @staticmethod
    def _findObjById(id):
        raise NotImplementedError
    
    def _doAdd(self):
        raise NotImplementedError
    
    def _doFetch(self):
        raise NotImplementedError
    
    def _doUpdate(self):
        raise NotImplementedError
    
    def _doRemove(self):
        raise NotImplementedError
    
    def getResult(self):
        funcname = "_do" + self._operationType.title()
        result = eval("self." + funcname + "()")
        return result
    
###############################################################################
# CountryService
###############################################################################    
class CountryService(ServiceBase):
    def __init__(self, request):
        super(CountryService, self).__init__(request)
        self._data['code'] = self.r('code')
        self._data['name'] = self.r('name')

    @staticmethod
    def _findObjById(id):
        return Country.objects.filter(code=id)[0]
    
    def _doAdd(self):
        country = Country(code=self.d('code'), 
                          name=self.d('name'))
        country.save()
        return country.__on__()
    
    def _doFetch(self):
        return [ x.__on__() for x in Country.objects.all() ]
    
    def _doUpdate(self):
        country = self._findObjById(self.d('code'))
        country.name = self.d('name')
        country.save()
        return country.__on__() 
    
    def _doRemove(self):
        country = self._findObjById(self.d('code'))
        country.delete()
        return {'code': self.d('code')}

###############################################################################
# TeamService
###############################################################################    
class TeamService(ServiceBase):
    def __init__(self, request):
        super(TeamService, self).__init__(request)
        self._data['id'] = self.r('id')
        self._data['name'] = self.r('name')
        self._data['country'] = self.r('country')
        self._data['lastLeague'] = self.r('lastLeague')
        
    def _findObjById(self, id):
        return Team.objects.filter(id=id)[0]
    
    def _doAdd(self):
        country = CountryService._findObjById(self.d('country'))
        league = LeagueService._findObjById(self, self.d('league'))
        team = Team(id=self.d('id'), 
                    name=self.d('name'),
                    country=country,
                    lastLeague=league)
        team.save()
        return team.__on__()
    
    def _doFetch(self):
        return [ x.__on__() for x in Team.objects.all() ]
    
    def _doUpdate(self):
        country = CountryService._findObjById(self.d('country'))
        league = LeagueService._findObjById(self, self.d('league'))
        
        team = self._findObjById(self.d('id'))
        team.name = self.d('name')
        team.country = country
        team.lastLeague = league
        team.save()
        return team.__on__() 
    
    def _doRemove(self):
        team = self._findObjById(self.d('id'))
        team.delete()
        return {'id': self.d('id')}

###############################################################################
# LeagueService
###############################################################################    
class LeagueService(ServiceBase):
    def __init__(self, request):
        super(LeagueService, self).__init__(request)
        self._data['id'] = self.r('id')
        self._data['name'] = self.r('name')
        self._data['country'] = self.r('country')
        self._data['level'] = self.r('level')
        self._data['numOfTeams'] = self.r('numOfTeams')
        self._data['numPromoted'] = self.r('numPromoted')
        self._data['numRelegated'] = self.r('numRelegated')
        
    def _findObjById(self, id):
        return League.objects.filter(id=id)[0]
    
    def _doAdd(self):
        country = CountryService._findObjById(self.d('country'))
        
        league = League(id=self.d('id'), 
                        name=self.d('name'),
                        country=country,
                        level=self.d('level'),
                        numOfTeams=self.d('numOfTeams'),
                        numPromoted=self.d('numPromoted'),
                        numRelegated=self.d('numRelegated'))
        league.save()
        return league.__on__()
    
    def _doFetch(self):
        return [ x.__on__() for x in League.objects.all() ]
    
    def _doUpdate(self):
        country = CountryService._findObjById(self.d('country'))
        league = self._findObjById(self.d('id'))
        league.name = self.d('name')
        league.country = country
        league.level = self.d('level')
        league.numOfTeams = self.d('numOfTeams')
        league.numPromoted = self.d('numPromoted')
        league.numRelegated=self.d('numRelegated')
        league.save()
        return league.__on__() 
    
    def _doRemove(self):
        league = self._findObjById(self.d('id'))
        league.delete()
        return {'id': self.d('id')}

###############################################################################
# Service Wrappers
###############################################################################
@json_response
def country_service_wrapper(request):
    s = CountryService(request)
    return s.getResult()

@json_response
def team_service_wrapper(request):
    s = TeamService(request)
    return s.getResult()

@json_response
def league_service_wrapper(request):
    s = LeagueService(request)
    return s.getResult()

def reset(request):
    from openphantasy.reset import nuke
    nuke()
    return HttpResponse("Done")
